﻿using System;
using System.Net.Sockets;
using CommonTypes.Server;
using CommonTypes.Server.Operations;
using Server.Model;

namespace Server.Services
{
    public class MergingManager
    {
        public static void Synchronize( string currentPrimary, ServerData serverData )
        {
            System.Console.WriteLine( "I'm going to synchronize with the server" );
            System.Console.WriteLine( String.Format( "My logical clock is {0}", serverData.ServerLogicalClock ) );
            serverData.PerformingSync = true;
            IServerToServer primary = serverData.ServersInformation.ServersProxy[ currentPrimary ];
            try
            {
                Operation[ ] list = primary.SynchronizeServer( serverData.ServerLogicalClock );

                System.Console.WriteLine( String.Format( "I'm about to receive {0} requests.", list.Length ) );

                foreach( Operation operation in list )
                {
                    if( operation is AddOperation )
                    {
                        System.Console.WriteLine( "I'm processing a Add Operation" );
                        AddOperation op = operation as AddOperation;
                        if( !serverData.Operations.ContainsKey( op.LogicalNumber ) )
                        {
                            if( serverData.UsersList.ContainsKey( op.ClientId ) )
                                serverData.UsersList[ op.ClientId ].Location = op.ClientLocation;
                            else
                                serverData.UsersList.Add( op.ClientId, new User( op.ClientId, op.ClientLocation ) );
                            serverData.Operations.Add( op.LogicalNumber, op );
                            serverData.ServerLogicalClock++;
                        }
                        continue;
                    }
                    if( operation is RemoveOperation )
                    {
                        System.Console.WriteLine( "I'm processing a Remove Operation" );
                        RemoveOperation op = operation as RemoveOperation;
                        if( !serverData.Operations.ContainsKey( op.LogicalNumber ) )
                        {
                            if( serverData.UsersList.ContainsKey( op.ClientId ) )
                                serverData.UsersList.Remove( op.ClientId );
                            serverData.Operations.Add( op.LogicalNumber, op );
                            serverData.ServerLogicalClock++;
                        }
                        continue;
                    }
                    if( operation is TicketGeneration )
                    {
                        System.Console.WriteLine( "I'm processing a Ticket Generation Operation" );
                        TicketGeneration op = operation as TicketGeneration;
                        if( !serverData.Operations.ContainsKey( op.LogicalNumber ) )
                        {
                            serverData.TicketNumber = op.TicketNumber;
                            serverData.Operations.Add( op.LogicalNumber, op );
                            serverData.ServerLogicalClock++;
                        }
                        continue;
                    }
                }

                System.Console.WriteLine( "I've done the sync!" );
            }
            catch( SocketException )
            {
                System.Console.WriteLine( "I can't speak with the primary..." );
            }
            serverData.PerformingSync = false;
        }
    }
}